package pl.siwoz.search.app;

import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

import pl.siwoz.search.engine.SearchEngine;

import com.vaadin.Application;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Window.CloseEvent;
import com.vaadin.ui.Window.CloseListener;
import com.vaadin.ui.Window.Notification;

@SuppressWarnings("serial")
public class DrugSearchApplication extends Application {

	private static Logger logger = Logger.getLogger("DrugSearchApplication");
	private static SearchEngine searchEngine;

	private String[] columns = new String[] { "Nazwa",
			"Dopasowana substancja aktywna", "Ilość", "Jednostka" };

	static {
		try {
			searchEngine = new SearchEngine();
		} catch (SQLException e) {
			logger.log(Level.SEVERE, e.getMessage());
			logger.log(Level.SEVERE, e.getSQLState());
		}
	}

	private static String excludeSubstance;
	private static String onlySubstance;
	private static Window mainWindow;

	@Override
	public void init() {

		setTheme("volt");

		mainWindow = initWindow();
		final VerticalLayout layout = initLayout();

		Label h1 = new Label(
				"<h1>Wyszukiwarka zamienn<span class=\"red\">i</span>ków <span class=\"red\">lek</span>ów</h1>",
				Label.CONTENT_XHTML);
		h1.setStyleName("webapp-title");
		layout.addComponent(h1);
		layout.setComponentAlignment(h1, Alignment.MIDDLE_CENTER);

		/*
		 * Horizontal layout with search text field and a search button
		 */
		HorizontalLayout searchLayout = new HorizontalLayout();
		searchLayout.setSpacing(true);

		final TextField searchField = initSearchField();
		searchLayout.addComponent(searchField);

		final Button searchButton = initSearchButton();
		searchLayout.addComponent(searchButton);

		final Button additionalOptions = initAdditionsButton();
		searchLayout.addComponent(additionalOptions);

		layout.addComponent(searchLayout);
		layout.setComponentAlignment(searchLayout, Alignment.MIDDLE_CENTER);

		/*
		 * Table with results of search
		 */
		final Table table = initTable();
		layout.addComponent(table);

		/*
		 * Click listener on search button.
		 */
		searchButton.addListener(new Button.ClickListener() {

			@Override
			public void buttonClick(ClickEvent event) {
				if (null == searchField.getValue()
						|| searchField.getValue() == "") {
					mainWindow.showNotification("Nie wpisałeś zapytania.");
				} else {
					try {
						logger.log(Level.INFO,
								"Query : " + searchField.getValue()
										+ ". [Options] Exclude substance : "
										+ excludeSubstance
										+ ", Only substance : " + onlySubstance);

						if (null != excludeSubstance) {
							table.setContainerDataSource(searchEngine.search(
									searchField.getValue().toString(),
									excludeSubstance, false));
							mainWindow
									.showNotification("Wyniki wyszukiwania dla zapytania : "
											+ searchField.getValue()
											+ ". Nie zawierające substancje: "
											+ excludeSubstance);
						} else if (null != onlySubstance) {
							table.setContainerDataSource(searchEngine.search(
									searchField.getValue().toString(),
									onlySubstance, true));
							mainWindow
									.showNotification("Wyniki wyszukiwania dla zapytania : "
											+ searchField.getValue()
											+ ". Zawirające substancje: "
											+ onlySubstance);
						} else {
							table.setContainerDataSource(searchEngine
									.search(searchField.getValue()));
							if (table.size() == 0) {
								mainWindow.showNotification(
										"Nie znaleziono zamiennika",
										Notification.TYPE_WARNING_MESSAGE);
							} else {
								mainWindow
										.showNotification("Wyniki wyszukiwania dla zapytania : "
												+ searchField.getValue());
							}
						}
						table.setColumnHeaders(columns);
					} catch (SQLException e) {
						logger.log(Level.SEVERE, e.getMessage());
					}

					excludeSubstance = null;
					onlySubstance = null;
				}
			}

		});

		additionalOptions.addListener(new Button.ClickListener() {

			@Override
			public void buttonClick(ClickEvent event) {
				mainWindow.addWindow(initOptionsWindow());

			}
		});

		Label footer = new Label(
				"<p>2011. Anton Kozik, Wiktor Krzyżanowski</p>"
						+ "<p>Projekt \"Wyszukiwarka zamienników leków\". Przedmiot - "
						+ "\"Systemy Informacyjne w Ochronie Zdrowia\".</p>",
				Label.CONTENT_XHTML);
		footer.addStyleName("font-bold");
		layout.addComponent(footer);
		layout.setComponentAlignment(footer, Alignment.BOTTOM_LEFT);
		mainWindow.addComponent(layout);
		setMainWindow(mainWindow);
	}

	protected Window initOptionsWindow() {

		final Window optionsWindow = new Window("Opcje");

		/*
		 * Additional options.
		 */

		FormLayout additionalSearchOptions = new FormLayout();
		additionalSearchOptions.setSpacing(true);

		final TextField onlySubstanceTextField = new TextField();
		onlySubstanceTextField.setColumns(14);
		final TextField excludeSubstanceTextField = new TextField();
		excludeSubstanceTextField.setColumns(14);
		final CheckBox excludeSubstanceCheckBox = new CheckBox(
				"Z wyłączeniem substancji", new Button.ClickListener() {

					@Override
					public void buttonClick(ClickEvent event) {
						if (excludeSubstanceTextField.isEnabled()) {
							excludeSubstanceTextField.setEnabled(false);
						} else {
							excludeSubstanceTextField.setEnabled(true);
							onlySubstanceTextField.setValue(null);
						}

					}
				});
		excludeSubstanceCheckBox.setImmediate(true);
		excludeSubstanceTextField.setEnabled(false);

		final CheckBox onlySubstanceCheckBox = new CheckBox(
				"Wylącznie z substancją", new Button.ClickListener() {

					@Override
					public void buttonClick(ClickEvent event) {
						if (onlySubstanceTextField.isEnabled()) {
							onlySubstanceTextField.setEnabled(false);
						} else {
							onlySubstanceTextField.setEnabled(true);
							excludeSubstanceTextField.setValue(null);
						}
					}
				});
		onlySubstanceCheckBox.setImmediate(true);
		onlySubstanceTextField.setEnabled(false);

		additionalSearchOptions.addComponent(excludeSubstanceCheckBox);
		additionalSearchOptions.addComponent(excludeSubstanceTextField);

		additionalSearchOptions.addComponent(onlySubstanceCheckBox);
		additionalSearchOptions.addComponent(onlySubstanceTextField);

		final Button choseButton = new Button("OK");

		choseButton.addListener(new Button.ClickListener() {

			@Override
			public void buttonClick(ClickEvent event) {
				if (null != excludeSubstanceTextField.getValue()) {
					excludeSubstance = excludeSubstanceTextField.getValue()
							.toString();
					onlySubstance = null;
				} else if (null != onlySubstanceTextField.getValue()) {
					onlySubstance = onlySubstanceTextField.getValue()
							.toString();
					excludeSubstance = null;
				}
				mainWindow.removeWindow(optionsWindow);
			}
		});

		additionalSearchOptions.addComponent(choseButton);
		additionalSearchOptions.setComponentAlignment(choseButton,
				Alignment.BOTTOM_RIGHT);
		optionsWindow.setPositionX(500);
		optionsWindow.setPositionY(170);
		optionsWindow.setWidth("230px");
		optionsWindow.setModal(true);
		optionsWindow.addComponent(additionalSearchOptions);
		additionalSearchOptions.setSizeFull();
		return optionsWindow;
	}

	private Button initAdditionsButton() {
		final Button additionalOptions = new Button("Opcje");
		additionalOptions.setIcon(new ThemeResource("../runo/icons/16/ok.png"));
		return additionalOptions;
	}

	private Button initSearchButton() {
		Button searchButton = new Button("Szukaj");
		searchButton.setIcon(new ThemeResource("../runo/icons/16/globe.png"));
		searchButton.setClickShortcut(KeyCode.ENTER);
		return searchButton;
	}

	private TextField initSearchField() {
		final TextField queryField = new TextField();
		queryField.setColumns(20);
		queryField.setStyleName("search-field");
		queryField.setInputPrompt("Na przykład, APAP");
		return queryField;
	}

	private Window initWindow() {
		final Window mainWindow = new Window("Drug Search Engine");

		mainWindow.addListener(new CloseListener() {

			@Override
			public void windowClose(CloseEvent e) {
				searchEngine.close();
			}

		});
		return mainWindow;
	}

	private Table initTable() {
		Table table = new Table();
		table.setEditable(false);
		table.setSizeFull();
		table.setStyleName("top-margin");
		table.addContainerProperty("Nazwa", String.class, null);
		table.addContainerProperty("Dopasowana substancja aktywna",
				String.class, null);
		table.addContainerProperty("Ilosc", String.class, null);
		table.addContainerProperty("Jednostka", String.class, null);
		table.setColumnHeaders(columns);
		return table;
	}

	private VerticalLayout initLayout() {
		VerticalLayout vl = new VerticalLayout();
		vl.setSpacing(true);
		vl.setSizeFull();
		return vl;
	}

}